package com.dmzc.stage3.Unsafe;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashSet;

/***
 * 根据偏移量估算对象大小
 */
public class Test3 {
    public static void main(String[] args) throws Exception {
        Guard guard = new Guard();
        System.out.println(sizeof(guard));
    }

    static class Guard {
        private int ACCESS_ALLOWED = 1;

        public boolean giveAccess() {
            return 42 == ACCESS_ALLOWED;
        }
    }

    public static long sizeof(Object o) throws Exception {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe unsafe = (Unsafe) f.get(null);
        HashSet<Field> fields = new HashSet<>();
        Class c = o.getClass();
        while (c != Object.class) {
            for (Field field : c.getDeclaredFields()) {
                if ((field.getModifiers() & Modifier.STATIC) == 0) {
                    fields.add(field);
                }
            }
            c = c.getSuperclass();
        }
        long maxSize = 0;
        for (Field field : fields) {
            long offset = unsafe.objectFieldOffset(field);
            if (offset > maxSize) {
                maxSize = offset;
            }
        }
        return ((maxSize / 8) + 1) * 8;
    }
}
